#ifndef _ASSET_MANAGER_H_
#define _ASSET_MANAGER_H_

#include "Asset.h"
#include "TextureAsset.h"
#include "AudioAsset.h"
#include <unordered_map>
#include <memory>
#include <functional>
#include <string>
#include <vector>

// 资源管理器类
class AssetManager
{
public:
    // 获取单例
    static AssetManager* GetInstance();

    // 资源加载状态的观察者接口
    using AssetLoadCallback = std::function<void(const std::string&, bool)>;

    // 注册状态观察者
    void RegisterLoadCallback(AssetLoadCallback callback);

    // 创建资源
    template<typename T, typename... Args>
    std::shared_ptr<T> CreateAsset(const std::string& id, Args&&... args)
    {
        if (HasAsset(id))
            return std::dynamic_pointer_cast<T>(GetAsset(id));

        auto asset = std::make_shared<T>(id, std::forward<Args>(args)...);
        m_assets[id] = asset;
        return asset;
    }

    // 添加已存在资源
    template<typename T>
    void AddExistingAsset(const std::string& id, std::shared_ptr<T> asset) {
        m_assets[id] = asset;
    }

    // 获取资源
    std::shared_ptr<Asset> GetAsset(const std::string& id) const;

    // 强制类型获取资源
    template<typename T>
    std::shared_ptr<T> GetAsset(const std::string& id) const
    {
        auto asset = GetAsset(id);
        return asset ? std::dynamic_pointer_cast<T>(asset) : nullptr;
    }

    // 检查资源是否存在
    bool HasAsset(const std::string& id) const;

    // 加载资源
    bool LoadAsset(const std::string& id);

    // 卸载资源
    void UnloadAsset(const std::string& id);

    // 加载所有资源
    bool LoadAllAssets();

    // 卸载所有资源
    void UnloadAllAssets();

    // 获取指定类型的资源列表
    std::vector<std::shared_ptr<Asset>> GetAssetsByType(AssetType type) const;

    // 清理未使用的资源
    void GarbageCollect();

protected:
    AssetManager() = default;
    ~AssetManager() = default;

private:
    static AssetManager* s_instance;
    std::unordered_map<std::string, std::shared_ptr<Asset>> m_assets;
    std::vector<AssetLoadCallback> m_loadCallbacks;

    // 通知观察者
    void NotifyLoadStatus(const std::string& id, bool success);
};

#endif // !_ASSET_MANAGER_H_
